/* See COPYRIGHT for copyright information. */

#include <inc/mmu.h>
#include <inc/memlayout.h>
#include <inc/trap.h>

#include <kern/picirq.h>


###################################################################
# exceptions/interrupts
###################################################################

/* The TRAPHANDLER macro defines a globally-visible function for handling
 * a trap.  It pushes a trap number onto the stack, then jumps to _alltraps.
 * Use TRAPHANDLER for traps where the CPU automatically pushes an error code.
 */
#define TRAPHANDLER(name, num)						\
	.data			;\
	.long name		;\
	.text	    		;\
	.globl name;		/* define global symbol for 'name' */	\
	.type name, @function;	/* symbol type is function */		\
	.align 2;		/* align function definition */		\
	name:			/* function starts here */		\
	pushl $(num);							\
	jmp _alltraps


/* Use TRAPHANDLER_NOEC for traps where the CPU doesn't push an error code.
 * It pushes a 0 in place of the error code, so the trap frame has the same
 * format in either case.
 */
#define TRAPHANDLER_NOEC(name, num)					\
	.data			;\
	.long name		;\
	.text			;\
	.globl name;							\
	.type name, @function;						\
	.align 2;							\
	name:								\
	pushl $0;							\
	pushl $(num);							\
	jmp _alltraps

.text

/*
 * Lab 3: Your code here for generating entry points for the different traps.
 */

/*
	Table 9-7. Error-Code Summary

Description                       Interrupt     Error Code
Number

Divide error                       0            No
Debug exceptions                   1            No
Breakpoint                         3            No
Overflow                           4            No
Bounds check                       5            No
Invalid opcode                     6            No
Coprocessor not available          7            No
System error                       8            Yes (always 0)
Coprocessor Segment Overrun        9            No
Invalid TSS                       10            Yes
Segment not present               11            Yes
Stack exception                   12            Yes
General protection fault          13            Yes
Page fault                        14            Yes
Coprocessor error                 16            No
Two-byte SW interrupt             0-255         No
*/
	.data
	.globl idt_handlers
idt_handlers:
	/* 0(T_DIVIDE) ~ 19(T_SIMDERR) */
	TRAPHANDLER_NOEC(H_DIVIDE, T_DIVIDE)
	TRAPHANDLER_NOEC(H_DEBUG, T_DEBUG)
	TRAPHANDLER_NOEC(H_NMI, T_NMI)
	TRAPHANDLER_NOEC(H_BRKPT, T_BRKPT)
	TRAPHANDLER_NOEC(H_OFLOW, T_OFLOW)
	TRAPHANDLER_NOEC(H_BOUND, T_BOUND)
	TRAPHANDLER_NOEC(H_ILLOP, T_ILLOP)
	TRAPHANDLER_NOEC(H_DEVICE, T_DEVICE)
	TRAPHANDLER(H_DBLFLT, T_DBLFLT)
 	TRAPHANDLER_NOEC(H_COPROC, T_COPROC)
	TRAPHANDLER(H_TSS, T_TSS)
	TRAPHANDLER(H_SEGNP, T_SEGNP)
	TRAPHANDLER(H_STACK, T_STACK)
	TRAPHANDLER(H_GPFLT, T_GPFLT)
	TRAPHANDLER(H_PGFLT, T_PGFLT)
 	TRAPHANDLER_NOEC(H_RES, T_RES)
	TRAPHANDLER_NOEC(H_FPERR, T_FPERR)
	TRAPHANDLER_NOEC(H_ALIGN, T_ALIGN)
	TRAPHANDLER_NOEC(H_MCHK, T_MCHK)
	TRAPHANDLER_NOEC(H_SIMDERR, T_SIMDERR)
	/* T_SYSCALL */
	TRAPHANDLER_NOEC(H_SYSCALL, T_SYSCALL)
	.data
	.globl irq_handlers
irq_handlers:
	/* 32 ~ 47 */
	TRAPHANDLER_NOEC(H_IRQ0, T_IRQ0)
	TRAPHANDLER_NOEC(H_IRQ1, T_IRQ1)
	TRAPHANDLER_NOEC(H_IRQ2, T_IRQ2)
	TRAPHANDLER_NOEC(H_IRQ3, T_IRQ3)
	TRAPHANDLER_NOEC(H_IRQ4, T_IRQ4)
	TRAPHANDLER_NOEC(H_IRQ5, T_IRQ5)
	TRAPHANDLER_NOEC(H_IRQ6, T_IRQ6)
	TRAPHANDLER_NOEC(H_IRQ7, T_IRQ7)
	TRAPHANDLER_NOEC(H_IRQ8, T_IRQ8)
	TRAPHANDLER_NOEC(H_IRQ9, T_IRQ9)
	TRAPHANDLER_NOEC(H_IRQ10, T_IRQ10)
	TRAPHANDLER_NOEC(H_IRQ11, T_IRQ11)
	TRAPHANDLER_NOEC(H_IRQ12, T_IRQ12)
	TRAPHANDLER_NOEC(H_IRQ13, T_IRQ13)
	TRAPHANDLER_NOEC(H_IRQ14, T_IRQ14)
	TRAPHANDLER_NOEC(H_IRQ15, T_IRQ15)

/*
 * Lab 3: Your code here for _alltraps
 */
	.text
_alltraps:
	/* 1.  push values to make the stack look like a struct Trapframe */
	pushl %ds
	pushl %es
	pushal
	/* 2. load GD_KD into %ds and %es */
	movw $GD_KD, %ax
	movw %ax, %ds
	movw %ax, %es
	/* 3. pushl %esp to pass a pointer to the Trapframe as an argument to trap() */
	pushl %esp
	/* 4. call trap */
	call trap
